﻿namespace LS.Project.Controllers
{
    [AllowAnonymous]
    public class LoginController : Controller
    {
        #region LoginController
        ISysUserService _userService;
        private readonly IHttpContextAccessor _httpContextAccessor;
        private readonly ICache _cache;
        private readonly IEventPublisher _eventPublisher;
        private readonly ICaptcha _captcha;
        private readonly ISysConfigurationService _configurationService;
        //构造器注入  
        public LoginController(ISysUserService userService, IEventPublisher eventPublisher, ISysConfigurationService configurationService, IOptions<CacheOptions> cacheOptions, ICaptcha captcha,
            Func<string, ISingleton, object> resolveNamed, IHttpContextAccessor httpContextAccessor)
        {
            _userService = userService;
            _cache = resolveNamed(cacheOptions.Value.CacheType.ToString(), default) as ICache;
            _httpContextAccessor = httpContextAccessor;
            _eventPublisher = eventPublisher; 
            _captcha = captcha;
            _configurationService = configurationService;
        }
        #endregion


        public async Task<ActionResult> Index()
        {
            ViewBag.CaptchaKey = Guid.NewGuid().ToString();
            //获取系统参数
             var  sysinfo= await GetSysInfo();
            ViewBag.SysTitle = sysinfo.SysTitle;
            return View();
        }
        /// <summary>
        /// 自动登录
        /// </summary>
        /// <returns></returns>
        public async Task<ActionResult> AutoLogin()
        {
            string token = Request.Query["token"];

            if (string.IsNullOrEmpty(token))
            {
                return RedirectToRoute("Default", new { Controller = "Error", Action = "CustomerMsg", msg = "token参数获取失败，请重新登录授权" });
            }

            var (isVaild, webtoken, tokenInfo) = JWTEncryption.Validate(token);

            if (!isVaild)
            {
                return RedirectToRoute("Default", new { Controller = "Error", Action = "CustomerMsg", msg = "token验证失败，请重新登录授权" });
            }
            var clent = Parser.GetDefault().Parse(_httpContextAccessor.HttpContext.Request.Headers["User-Agent"]);
            var LastLoginBrowser = clent.UA.Family + clent.UA.Major;
            var LastLoginOs = clent.OS.Family + clent.OS.Major;

            SysUserModel suser = new SysUserModel
            {
                ID = tokenInfo.Claims[ClaimConst.CLAINM_USERID].ParseToLong(),
                UserName = tokenInfo.Claims[ClaimConst.CLAINM_ACCOUNT].ToString(),
                RealName = tokenInfo.Claims[ClaimConst.CLAINM_NAME].ToString(),
                UserType = tokenInfo.Claims[ClaimConst.CLAINM_SUPERADMIN].ParseToInt(),
                UserPhoto = "/images/head.png"
            };
            await SetUserLogin(suser);
            return RedirectToRoute("Default", new { Controller = "Admin", Action = "Index" });
           

        }

        #region 公共方法
        /// <summary>
        /// 登录操作
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public async Task<ResponseDataResult> Loging([FromBody]SysLoginViewModel vm)
        {
            ResponseDataResult rdr = new ResponseDataResult();
            rdr.code = 0;
            string name = vm.UserName;
            string pwd = vm.UserPwd;
            string strwhere = string.Empty;
            if (string.IsNullOrWhiteSpace(name) || string.IsNullOrWhiteSpace(pwd))
            {
                rdr.message = "账号密码错误";
                rdr.code = 1;
                return rdr;
            }
            
            if(!string.IsNullOrEmpty(vm.CaptchaKey) && !string.IsNullOrEmpty(vm.CaptchaCode))
            {
                var  captcheFlag= _captcha.Validate(vm.CaptchaKey, vm.CaptchaCode);
                if (!captcheFlag)
                {
                    rdr.message = "验证码错误";
                    rdr.code = 1;
                    return rdr;
                }
            }
            var clent = Parser.GetDefault().Parse(_httpContextAccessor.HttpContext.Request.Headers["User-Agent"]);
            var LastLoginBrowser = clent.UA.Family + clent.UA.Major;
            var LastLoginOs = clent.OS.Family + clent.OS.Major;

            var systemSettings = App.GetOptions<SystemSettingsOptions>();
            //var ss = MD5Encryption.Encrypt(pwd);
            if (systemSettings.SuperAdminName == vm.UserName)
            {
                if(systemSettings.SuperAdminPwd == MD5Encryption.Encrypt(pwd))
                {
                    SysUserModel suser = new SysUserModel
                    {
                        ID = 999999,
                        UserName = "admin",
                        RealName="超级管理员",
                        UserType = 0,
                        UserPhoto = "/images/head.png"
                    };
                    await SetUserLogin(suser);
                    rdr.data = new { targetUrl = "/admin" };
                    return rdr;
                }
            }
            else
            {
                Log.Warning($"{pwd}={MD5Encryption.Encrypt(pwd)}");
                var model = await _userService.Login(RequestHelper.FilterParam(name), MD5Encryption.Encrypt(pwd));
                if (model != null )
                {
                    string Photo = "/images/head.png";
                    if (model.UserStatus == 0 || model.IsDeleted == 1)
                    {
                        // 增加登录日志
                        await _eventPublisher.PublishAsync(new ChannelEventSource("Create:LoginLog",
                            new SysLoginLogEntity
                            {
                                CreateDate = DateTime.Now,
                                LoginName = name,
                                LoginIp = HttpNewUtil.Ip,
                                LoginState = 1,
                                LoginMsg = model.UserStatus==0?"此账号未审核": "此账号已删除",
                                Browser = LastLoginBrowser,
                                OperatingSystem = LastLoginOs,

                            }));
                        rdr.message = ResponseHelper.PARAMETER_CZHWSH;
                        rdr.code = 1;
                        return rdr;
                    }
                    SysUserModel suser = new SysUserModel
                    {
                        ID = model.Id,
                        UserName = model.UserName,
                        UserType = model.UserType,
                        RealName =model.RealName,
                        UserPhoto = string.IsNullOrEmpty(model.Avatar) ? Photo : model.Avatar
                    };
                    await SetUserLogin(suser);
                    rdr.data = new { targetUrl = "/admin" };
                    rdr.code = 0;
                    // 增加登录日志
                    await _eventPublisher.PublishAsync(new ChannelEventSource("Create:LoginLog",
                        new SysLoginLogEntity
                        {
                            CreateDate = DateTime.Now,
                            LoginName = suser.UserName,
                            LoginIp = HttpNewUtil.Ip,
                            LoginState = 0,
                            LoginMsg = "登录成功",
                            Browser = LastLoginBrowser,
                            OperatingSystem = LastLoginOs,
                           
                        }));
                    return rdr;
                }
            }
            // 增加登录日志
            await _eventPublisher.PublishAsync(new ChannelEventSource("Create:LoginLog",
                new SysLoginLogEntity
                {
                    CreateDate = DateTime.Now,
                    LoginName = name,
                    LoginIp = HttpNewUtil.Ip,
                    LoginState =1,
                    LoginMsg = "账号或密码不正确",
                    Browser = LastLoginBrowser,
                    OperatingSystem = LastLoginOs,

                }));
            rdr.message = "账号密码错误";
            rdr.code = 1;
            return rdr;
        }

        /// <summary>
        /// 登录退出
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<dynamic> Loginout()
        {
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);

            //return View("Index");
            return Redirect("/Login");
        }
        [HttpPost]
        public ResponseDataResult LoginOutAuth()
        {
            ResponseDataResult rdr = new ResponseDataResult();
            rdr.code = 0;
            rdr.message = "OK";
            if (App.User != null)
            {
                var userid = App.User.FindFirst(ClaimConst.CLAINM_USERID)?.Value;
                if (!string.IsNullOrEmpty(userid))
                {
                    _cache.Del("CurentMenu_" + userid);
                    _cache.Del("CurentPower_" + userid);
                    _cache.Del("LS_Nc6_SysInfo");
                }
            }
            return rdr;
        }


        [HttpGet]
        public FileStreamResult Captcha(string id)
        {
            var info = _captcha.Generate(id);
            // 有多处验证码且过期时间不一样，可传第二个参数覆盖默认配置。
            //var info = _captcha.Generate(id,120);
            var stream = new MemoryStream(info.Bytes);
            return File(stream, "image/gif");
        }
        #endregion


        #region 私用方法
        private async  Task SetUserLogin( SysUserModel suser)
        {
            var claims = new List<Claim>() {
                            new Claim(ClaimConst.CLAINM_USERID,suser.ID.ToString()), //ID
                             new Claim(ClaimConst.CLAINM_ACCOUNT,suser.UserName),   //账号
                            new Claim(ClaimConst.CLAINM_NAME,suser.RealName),  //姓名
                            new Claim(ClaimConst.CLAINM_SUPERADMIN,suser.UserType.ToString()) //存用户类型
                            };

            var identity = new ClaimsIdentity(claims, "Login");

            await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, new ClaimsPrincipal(identity));

            // 生成Token令牌
            //var accessToken = await _jwtBearerManager.CreateTokenAdmin(user);
            //var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
            //    {
            //        {ClaimConst.CLAINM_USERID, suser.ID},
            //        {ClaimConst.TENANT_ID, "0"},
            //        {ClaimConst.CLAINM_ACCOUNT, suser.UserName},
            //        {ClaimConst.CLAINM_NAME, suser.RealName},
            //        {ClaimConst.CLAINM_SUPERADMIN, suser.UserType}
            //    });

            //// 设置Swagger自动登录
            //_httpContextAccessor.HttpContext.SigninToSwagger(accessToken);

            //// 生成刷新Token令牌
            //var refreshToken = JWTEncryption.GenerateRefreshToken(accessToken, 30);

            //// 设置刷新Token令牌
            //_httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;

            //var httpContext = App.HttpContext;
            //await _eventPublisher.PublishAsync(new ChannelEventSource("Update:UserLoginInfo",
            //    new SysUser { Id = user.Id, LastLoginIp = httpContext.GetLocalIpAddressToIPv4(), LastLoginTime = DateTime.Now }));

            //string accessToken = string.Empty;
            //string refreshToken = string.Empty;
            //return new Tuple<string, string>(accessToken, refreshToken);
        }
       

        private async Task<SysInfoModel> GetSysInfo()
        {
            var sysinfo = new SysInfoModel();

            sysinfo.SysTitle = string.Empty;
            sysinfo.SysLogo = string.Empty;
            sysinfo.MuiltTab = 0;
            sysinfo.DefaultColor = "1";
            sysinfo.SysFooter = 0;
            sysinfo.SysCopyRight = "0";
            sysinfo.SysType = 0;
            //if (!_cache.Exists("LS_Nc6_SysInfo"))
            //{
            var result = await _configurationService.List(a => true, a => a.Id);
            foreach (var item in result)
            {
                switch (item.Code)
                {
                    case "SYSTITLE":
                        sysinfo.SysTitle = item.Args;
                        break;
                    case "SYSLOGO":
                        sysinfo.SysLogo = item.Args;
                        break;
                    case "MUILTTAB":
                        sysinfo.MuiltTab = item.Args == null ? 0 : item.Args.ParseToInt();
                        break;
                    case "DEFAULTCOLOR":
                        sysinfo.DefaultColor = item.Args;
                        break;
                    case "SYSFOOTER":
                        sysinfo.SysFooter = item.Args == null ? 0 : item.Args.ParseToInt();
                        break;
                    case "COPYRIGHT":
                        sysinfo.SysCopyRight = item.Args;
                        break;
                    case "SYSTYPE":
                        sysinfo.SysCopyRight = item.Args;
                        break;
                    case "BADWORD":
                        sysinfo.BadWord = item.Args;
                        break;
                    default:
                        break;
                }
            }
         
            //await _cache.SetAsync("LS_Nc6_SysInfo", sysinfo);
             _cache.Set("LS_Nc6_SysInfo", sysinfo);
            //}
            //else
            //{
            //    sysinfo = _cache.Get<SysInfoModel>("LS_Nc6_SysInfo");
            //}

            return sysinfo;

        }

        #endregion

    }
}